-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Simplify Link annotation handling #8972
Conversation
src/annotations.cr
Outdated
@@ -27,7 +27,7 @@ end | |||
annotation Flags | |||
end | |||
|
|||
# A `lib` can be marked with `@[Link(lib : String, ldflags : String, static : Bool, framework : String)]` | |||
# A `lib` can be marked with `@[Link(lib : String, *, ldflags : String, static : Bool, framework : String, pkg_config : String)]` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should add that static
is deprecated. Not in this line but further down. And maybe not mention it here at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should also note that CRYSTAL_LIBRARY_PATH
is added to the lookup paths.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tweaked the link annotation docs. CRYSTAL_LIBRARY_PATH
was already mentioned further down, but I removed some old references to hardcoded paths.
I removed mention of static
entirely, I presume that'll be gone by 1.0 if all goes well.
flags << " -L#{path}" | ||
# First, check pkg-config for the pkg-config module name if provided, then | ||
# check pkg-config with the lib name, then fall back to -lname | ||
if (pkg_config_name = ann.pkg_config) && (flag = pkg_config(pkg_config_name, static_build)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is giving more precedence to the pkg-config settings for the lib, instead of giving priority to the CRYSTAL_LIBRARY_PATH as it should. Otherwise having a local package for bdw-gc will override the patched embedded version we ship.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, it will, I don't think CRYSTAL_LIBRARY_PATH
was a good idea because it binds you to the "path" model of library lookup, which is outdated and replaced with pkgconfig (and PKG_CONFIG_PATH
)
A better solution is CRYSTAL_LIBRARY_OVERRIDES="gc=/path/to/whatever otherlib=-lwhatever"
which is far more robust and flexible by allowing you to replace any link annotation with arbitrary ldflags.
@RX14 I like the overall idea of this PR. The However, I'm not so sure yet about deprecating the I love the idea of |
By the way, I mentioned doing it this way more than a year ago: https://forum.crystal-lang.org/t/rfc-link-configuration/546/2?u=asterite . And there's no need for an environment variable to do it, it can just be a compiler flag. |
@asterite There are some |
Yeah, the lib/link relationship is many to many, additionally to one lib definition having many link annotations, the same link annotation could also be on many lib definitions. Using the lib name the behavior seems unclear in either scenario. |
Yeah, I was thinking of making I appreciate that |
Oh, but I thought I made the issue clear. For example, if there is a system wide installed |
Presumably in the distribution, where we would ship a In time, when |
@RX14 can you rebase this on master due to conflicts? |
Static linking per-library is not supported well on any platform we support, and the feature is rarely used. Deprecate it so we can simplify the linking process.
Yep. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comments in https://github.com/crystal-lang/crystal/pull/8972/files#r399834746 haven't been addressed.
We can merge this PR and see how it goes. Maybe in the future the compiler will need to add some pkg-config path to avoid breaking in some user setup. Like having a gc.pc that will prevent the embedded libraries to be linked. That will offer some workaround to the lookup priority changed.
The following entries in crystal-book should be updated
- https://github.com/crystal-lang/crystal-book/blob/master/using_the_compiler/README.md (due to
CRYSTAL_LIBRARY_PATH
mentions) - https://github.com/crystal-lang/crystal-book/blob/master/syntax_and_semantics/c_bindings/lib.md (due to
Link
annotation description)
I'd like to implement I'll address those comments. |
I would avoid designing CRYSTAL_LIBRARY_OVERRIDES before we discuss the story of a compiler configuration files in the .crystal folder. That will probably cover many stories together. How to override the libs link annotation is definitely one of the main stories to cover there. |
I think there's definitely need for a system/user-level override as well as project-level, and an env var is a good way to do that. Perhaps you want to wait on that but I'm not convinced it's neccesary. |
Co-authored-by: Brian J. Cardiff <bcardiff@gmail.com>
This pull request deprecates the
@[Link("lib", static: true)]
request to prefer static linking of libraries. The only use of this is a@[Link("gc", static: true)]
in the crystal repo. I have been unable to find any exmaples ofstatic: true
being used outside of this repo. The reason for this, I suspect, is because it doesn't work. People who want the existing behaviour can simply passldflags: "-l :libgc.a"
Also deprecated is passing positional arguments to
@[Link]
other than "lib" (nobody uses that either).Because of these simplifications, we can implement a new, simpler, linking algorithm with less code.
First, a
pkg_config
link argument is added, since almost all libraries have a different pkg-config name to thelib<foo>.so
name. For example,libz.so
iszlib.pc
,libgc.so
isbdw-gc.pc
. Only one of 10 different libs used by the crystal standard library was correctly detected using the original mechanism. Allowing pkg-config module names to be specified correctly allows the pkg-config mechanism to work properly, which makes linking far more reliable. The fallback remains-lfoo
as before.When neither
static: true
or--static
is specified, the current algorithm is identical to before, but with thepkg_config
argument added.static: true
is now ignored, and passing--static
simply passes-static
to the linker and--static
topkg-config
.